﻿using System;
using System.Linq;
using System.Text;
using Lucene.Net.Documents;

namespace Medianamik.Core.Index
{
	public class DocumentFactory
	{
        [CLSCompliant(false)]
        public virtual Document Create(NodeInstance pNodeInstance)
        {
            var d = new Document();
            var key = new Field("Key",IndexUtils.GetDocumentKey(pNodeInstance.Node.ID, pNodeInstance.Culture.Name), Field.Store.YES, Field.Index.UN_TOKENIZED);

            //Field documentType = new Field("DocumentType"
            //    , ((int)this.DocumentType ).ToString()
            //    , Field.Store.YES
            //    , Field.Index.UN_TOKENIZED );

            var nodeId = new Field("NodeId"
                , pNodeInstance.Node.ID.ToString("N")
                , Field.Store.YES
                , Field.Index.NO);

            var parentNodeId = new Field("ParentNodeId"
                , pNodeInstance.Node.ParentID.HasValue
                    ? pNodeInstance.Node.ParentID.Value.ToString("N")
                    : string.Empty
                , Field.Store.YES
                , Field.Index.NOT_ANALYZED);

            var nodeTypeId = new Field("NodeTypeId"
                , pNodeInstance.Node.NodeTypeID.ToString("N")
                , Field.Store.YES
                , Field.Index.NOT_ANALYZED);

            var parentTypeIds = new Field("ParentTypeIds"
                , string.Join(" ", pNodeInstance.Node.NodeType.GetParentIds(false).Select(id => id.ToString("N")).ToArray())
                , Field.Store.NO
                , Field.Index.ANALYZED);

            var cultureName = new Field("CultureName"
                , pNodeInstance.Culture.Name.ToLowerInvariant().Replace("-", string.Empty)
                , Field.Store.YES
                , Field.Index.NOT_ANALYZED);


            d.Add(key);
            d.Add(nodeId);
            d.Add(parentNodeId);
            d.Add(nodeTypeId);
            d.Add(parentTypeIds);
            d.Add(cultureName);

            foreach (var prop in pNodeInstance.Properties)
            {
                if (prop.GetType() != typeof(ManyToManyNodeProperty) || ((ManyToManyNodeProperty)prop).ForeignProperty.PrimaryMedianamikControlID.HasValue)
                {
                    var value = prop.Value == null ? string.Empty : prop.Value.ToString();
                    Field.Store store;
                    Field.Index index;
                    if (IndexProperty(prop, out store, out index))
                    {
                        d.Add(new Field("Property_" + prop.NodeTypePropertyID, value, store, index));
                    }
                }
            }

            d.Add(new Field("Content", GetContentValue(pNodeInstance), Field.Store.NO, Field.Index.ANALYZED));


            return d;
        }
        [CLSCompliant(false)]
        public virtual bool IndexProperty(NodeProperty pNodeProperty, out Field.Store store, out Field.Index index)
        {
            //var value = pNodeProperty.Value == null ? string.Empty : pNodeProperty.Value.ToString();
            if (pNodeProperty.IsOwnProperty && pNodeProperty.Indexable)
            {
                store = Field.Store.NO;
                index = Field.Index.ANALYZED;
                return true;
            }
            if (pNodeProperty.IsLookup)
            {
                store = Field.Store.YES;
                index = Field.Index.NOT_ANALYZED;
                return true;
            }
            store = Field.Store.NO;
            index = Field.Index.NO;
            return false;

        }
        
        public virtual string GetContentValue(NodeInstance pNodeInstance)
        {
            var content = new StringBuilder();
            foreach (var prop in pNodeInstance.Properties.Where(p => p.Indexable))
            {
                var value = prop.Value == null ? string.Empty : prop.Value.ToString();
                content.Append(value).Append(" ");
            }
            return content.ToString();
        }
	}
}
